﻿using System;

namespace 面向对象_结构
{
    class Program
    {
        int a;
        //public int MyProperty { get =>a; set=>a=value; } = 5;只有自动属性才能赋初始值
        public int Myproperty { get; set; } = 5;
        static void Main(string[] args)
            
        {
            //结构的调用
            Program b = new Program();//类类型必须new对象才能进行访问字段！
            //var c= b.a;
            Vector3 v;//// 1. 使用结构时，可以不用 new 对象，能直接访问 ，没有调用任何构造函数，从而提高了分配效率
            v.x = 5;
            v.y = 5;
            v.z = 5;
            v.size = 5;
            Vector3 v2 = new Vector3();//访问结构的属性前，需要 new 对象，避免某些实例成员未初始化完成
            v2.x = 60;
            v2.y = 60;
            v2.z = 60;
            v2.Z = 60;
            v2.size = 70;
            Console.WriteLine(v2);//因为to string 所以访问到的不是v2地址
           // 由属性的规则，我们推导出实例方法的规则：避免某些实例成员未初始化完成，在new 对象前不能访问
          //v.GetLenght();
            v2.GetLenght();
            //2. new 无参
            Vector3 vector1 = new Vector3(); // 必须自己对实例成员赋值，否则数据皆为默认值
            Console.WriteLine(vector1);
            //3.new 有参
            Vector3 vector2 = new Vector3(1,2,3,4);
            Console.WriteLine(vector2);
            //4. new 无参新语法糖
            //Vector3 vector3 = new Vector3 (){ };
            Vector3 vector3 = new Vector3 { x = 1, z = 2, y = 3, size = 4 };
            Console.WriteLine(vector3);
        }






    }

// 结构，关键字是 struct 
// 结构是值类型，不同于类类型，类类型是引用类型
// 将较小的类声明为结构，可以提高系统的处理效率。
//vector3 三维向量
// 结构不允许显式的写无参构造函数
// 存在构造函数，所有字段皆需赋值，自动属性必须赋值.
// 结构中，不能在实例字段后能赋初始值
// 结构中，不能在实例自动属性后赋初始值
// 结构中，私有实例成员只能在构造函数中赋初始值。
struct Vector3
{
    //public float a = 50; 结构中不能有实例成员，不能这样赋初始值
    public float x;
    public float y;
    public float z;
    public int size;
    public Vector3(float x, float y, float z, int size)//在结构里声明构造函数必须将全部字段进行声明，否则报错
    {
        this.x = x;
        this.y = y;
        this.z = z;
        this.size = size;
    }

    private static int Size { get; set; }//不强制赋值
    public float Z { get => z; set => z = value; }
    //private  float Y { get; set; } = 50f; //不可以这么赋值，但是加上static就可以这么赋值了
    private static float Y { get; set; } = 50;

    public static Vector3 a = new Vector3(1, 2, 3, 4);//// 实例字段不能赋初始值，但是静态的字段可以赋值
                                                      //public Vector3() { }不是静态的构造函数必须声明全部字段
    static Vector3() { }//可以写静态的无参构造函数
    public float GetLenght()//没参数的方法
    {
        size = 100;
        return 10;
    }

    public static float GetSize(float x, float y)//有参数的方法
    {
        return x * y;
    }

    public override string ToString()//重写
    {
        return $"x={x}; y={y}；z={z},size={size}";
    }
}
    // 结构与类：
    // 结构与类共享了大多数语法，结构比类有更多限制
    // 结构中，实例成员不能直接在声明的时候赋初始值，const 必须赋初始值，static 可以在字段声明后赋初始值（不强制）
    //  结构不可以显式声明无参构造函数以及析构函数(值类型要什么析构)
    //  结构的赋值实际上是构建新的结构实例并赋值。对新副本任何修改，不会改变源数据(明天讲struct 在 dic 中的应用注意事项)
    //  结构是值类型，而类是引用类型
    //  与类不同，结构实例化可以不用 new
    //   结构可以声明带参数的构造函数
    //  结构不能从结构或类类型继承，而且不能作为一个类的基类
    // 结构直接继承自 System.ValueType，后者继承自 System.Object
    // 结构也可以实现接口
    //结构的继承
    // （万物皆对象，结构是 ValueType，而ValueType又是继承自 object）
    // 结构不能继承结构或者类类型，但是能够继承接口，行为和class 继承接口保持一致
    struct book { }
    struct books { }//:book// 继承对象不能是结构 继承不是接口
    class bookss { }
    struct booksss { }//:bookss { }继承对象不能是类 继承不是接口
    interface Dog//接口
    {
        public void Dog();
    }
    struct Dogs : Dog//结构对象只能继承接口。
    {
        public void Dog()
        {
            Console.WriteLine("我能吃");
        }
    }
    
}
